/// 辅助 * 请求

import type { RequestConfig } from '@expresso/plus'
import type { AxiosResponse } from 'axios'
import { cache } from './cache'
import router from '@/router'

const requester = new Requester({

  timeout: 1000 * 60 * 2,

  reqInterceptors: [{
    onFulfilled(config) {
      if (['/fjfr/user_center/login'].includes(config.url ?? '')) {
        return config
      }
      else {
        const token = cache.getToken()
        if (token) {
          config.headers.Token = token
        }
        else {
          router.push('/login')
          return Promise.reject(new Error('未登录'))
        }
        return config
      }
    },
  }],
  resInterceptors: [{
    onFulfilled(response) {
      switch (response.status) {
        case 200: {
          const { formatter = 'data' } = response.config
          switch (formatter) {
            case 'response':
              return response
            case 'result':
              return response.data
            case 'data':
              return response.data.data
            default:
              return response
          }
        }

        default:
          return response
      }
    },
    onRejected(error) {
      console.log('error', error)
      const { response } = error
      switch (response?.status) {
        case 403: {
          router.push('/login')
          cache.clear()
          break
        }
      }
      return Promise.reject(error)
    },
  }],
})

type RequestConfigType = Omit<RequestConfig, 'url' | 'formatter'>
type FormatterType = Completed<RequestConfig['formatter']> | 'data' | 'page'
type Request = {
  <Data = any>(url: string, config: RequestConfigType): Promise<Data>
  <Data = any>(url: string, config: RequestConfigType, formatter: 'data'): Promise<Data>
  <Data = any>(url: string, config: RequestConfigType, formatter: 'page'):
    Promise<PaginationResult<Data>>
  <Data = any>(url: string, config: RequestConfigType, formatter: 'result'):
    Promise<ResponseResult<Data>>
  <Data = any>(url: string, config: RequestConfigType, formatter: 'response'):
    Promise<AxiosResponse<Data>>
  /*  <Data = any, Config extends RequestConfigType = RequestConfigType>(
    url: string,
    config: Config extends { data?: infer CData } ? RequestConfigType : RequestConfigType,
    formatter: 'response'
  ): Promise<AxiosResponse<Data, CData>> */
}

const request = (function (url: string, config: RequestConfigType, formatter?: FormatterType) {
  const configData = {
    url,
    ...config,
  } as RequestConfig
  if ([void 0, 'page', 'data'].includes(formatter)) {
    formatter = 'data'
  }
  configData.formatter = formatter as any
  return requester.request(configData)
}) as Request

function isSucceed(res: ResponseResult) {
  if ((res.code as any) == 200) {
    return true
  }
  Message.warning(res.message)
  return false
}

export { request, isSucceed }
